﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#if WINDOWS_PHONE
using Microsoft.Xna.Framework.Input.Touch;
#endif
#if WINDOWS
using Microsoft.Xna.Framework.Storage;
#endif
using Microsoft.Xna.Framework.Media;
using Neat;
using Neat.MenuSystem;
using Neat.EasyMenus;
using Neat.GUI;
using Neat.Mathematics;
using Neat.Graphics;
using System.IO;
namespace RiverRaidX
{
    public partial class RiverRaidGame : Screen
    {
        RiverRaidDesigner.RandomLevelGenerator rlg = new RiverRaidDesigner.RandomLevelGenerator();

        void LoadRandom()
        {
            rlg.Reseed(level);
            LoadLevel("random");
        }

        void LoadLevel(string filename)
        {
            if (filename == "random")
            {
                rlg.Generate();
                filename = "test.rrx";
            }

            int version = 1;
            if (!File.Exists(filename))
            {
                game.Console.WriteLine(filename + " does not exists.");
                return;
            }

            bool firstLevel = outerWalls.Count == 1;
            Vector2 offset = new Vector2(0, game.GameHeight);
            if (outerWalls.Count > 1)
                offset.Y = outerWalls[outerWalls.Count - 1].Y;
            else
            {
                outerWalls.Add(new Vector2(
                    (game.GameWidth - (game.GetTexture("bridge").Width * scale.X)) / 2f, ySpeed * speedBoostRate * 10000));
            }

            StreamReader sr = new StreamReader(filename);
            var versionId = sr.ReadLine();
            if (versionId.Trim() == "~2")
            {
                versionId = sr.ReadLine();
                version = 2;
            }
            if (versionId != "~inner")
            {
                //TODO: File is damaged
                sr.Close();
                return;
            }
            string s;
            while ((s = sr.ReadLine().Trim()) != "~outer")
            {
                var v = GeometryHelper.String2Vector(s) * ar + offset;
                v.X = (int)v.X;
                v.Y = (int)v.Y;
                innerWalls.Add(v);
            }
            while ((s = sr.ReadLine().Trim()) != "~entities")
            {
                var v = GeometryHelper.String2Vector(s) * ar + offset;
                
                if (version == 2)
                    //v.X = 1280 / 2 - v.X;
                    v.X = game.GameWidth / 2 - v.X;

                v.X = (int)v.X;
                v.Y = (int)v.Y;
                outerWalls.Add(v);
            }
            while (!sr.EndOfStream)
            {
                Entity e = new Entity();
                e.TextureName = "";
                var pos = GeometryHelper.String2Vector(sr.ReadLine());
                /*if (version == 2)
                    //pos.X = 1280 / 2 - pos.X;
                    pos.X = game.GameWidth/2 - pos.X;*/
                e.Position = ar * pos + offset;
                if (version == 2)
                    e.Position.X = game.GameWidth / 2 - e.Position.X;

                e.Flip = bool.Parse(sr.ReadLine());
                Items itype = (Items)(sr.ReadLine()[0]);
                e.ItemType = itype;
                e.ScorePoints = 10;
                e.WakeUpDistance = (yOffset > -2000) ? game.RandomGenerator.Next(10, 200) :
                            -game.RandomGenerator.Next(10, 1000);
                switch (itype)
                {
                    case Items.Fuel:
                        e.TextureName = "fuel";
                        e.Speed = 0;
                        e.Flip = false;
                        e.WakeUpDistance = 0;
                        e.ScorePoints = 500;
                        break;
                    case Items.Heli:
                        e.TextureName = "heli";
                        e.Speed = 5;
                        e.NoClip = false;
                        e.ScorePoints = 80;
                        break;
                    case Items.House:
                        e.TextureName = "house";
                        e.Speed = 0;
                        e.NoClip = true;
                        e.Immortal = true;
                        break;
                    case Items.Jet:
                        e.TextureName = "jet";
                        e.Speed = 10;
                        e.NoClip = true;
                        e.ScorePoints = 120;
                        e.WakeUpDistance = game.GameHeight;
                        break;
                    case Items.Ship:
                        e.TextureName = "ship";
                        e.Speed = 3;
                        e.NoClip = false;
                        e.ScorePoints = 100;
                        break;
                    case Items.Tree:
                        e.TextureName = "tree";
                        e.Speed = 0;
                        e.NoClip = true;
                        e.Immortal = true;
                        break;
                }
                var t = game.GetTexture(e.TextureName);
                e.Size = new Vector2(t.Width * scale.X, t.Height * scale.Y);
                if (e.TextureName != "") entities.Add(e);
            }
            //if (!firstLevel)
            {
                var lastwall = outerWalls[outerWalls.Count - 1];
                var b = new Entity();
                b.TextureName = "bridge";
                b.ItemType = Items.Bridge;
                b.ScorePoints = 2000;
                b.Speed = 0;
                b.NoClip = true;
                b.Position = new Vector2(lastwall.X, lastwall.Y - game.GetTexture(b.TextureName).Height * scale.Y);
                b.Size = new Vector2(game.GetTexture(b.TextureName).Width, game.GetTexture(b.TextureName).Height) * scale;
                entities.Add(b);
                checkpoints.Add(lastwall.Y - game.GetTexture(b.TextureName).Height * scale.Y);
                outerWalls.Add(new Vector2(
                   (game.GameWidth - (game.GetTexture("bridge").Width * scale.X)) / 2f, checkpoints[checkpoints.Count - 1]));
            }
            sr.Close();

            CreateRects();
        }

        void CreateRects()
        {
            var half = game.GameWidth / 2;
            walls = new List<Polygon>();
            for (int i = 1; i < outerWalls.Count; i++)
            {
                walls.Add(Polygon.BuildRectangle(
                    new Rectangle(0, (int)(outerWalls[i].Y),
                        (int)(outerWalls[i - 1].X), (int)(outerWalls[i - 1].Y - outerWalls[i].Y))));
                walls.Add(Polygon.BuildRectangle(
                   new Rectangle((int)(game.GameWidth - outerWalls[i - 1].X), (int)(outerWalls[i].Y),
                       (int)(outerWalls[i - 1].X), (int)(outerWalls[i - 1].Y - outerWalls[i].Y))));
            }

            for (int i = 1; i < innerWalls.Count; i++)
            {
                if (innerWalls[i - 1].X == 0) continue;
                walls.Add(Polygon.BuildRectangle(
                    new Rectangle((int)(half - innerWalls[i - 1].X), (int)(innerWalls[i].Y),
                        (int)(2 * innerWalls[i - 1].X), (int)(innerWalls[i - 1].Y - innerWalls[i].Y))));
            }
        }
    }
}